package org.junit.runners;

import static org.junit.Assert.assertEquals;

import java.util.Random;

import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * RunWith(NameAwareTestClassRunner.class)<br/>
 * Unfortunately, test case classes need to be "top-level" (ie not inner classes).<br/>
 * Usage: <code>public class &lt;YourTestClass&gt; extends DummyAbstract {}</code><br/>
 */
@RunWith(NameAwareTestClassRunner.class)
public class DummyAbstract {
    @Test
    public void dummy() {
        final String myName = this.getClass().getName() + ".dummy()";
        final String testName = NameAwareTestClassRunner.getName();
        System.out.println(String.format("[% 4d] %s %s", 
                Thread.currentThread().getId(), myName, goodOrBad(myName, testName)));

        // check the test name is as expected
        assertEquals(myName, testName);
        
        // non-deterministic attempt to trip up non-threadsafe changes
        snooze();
        assertEquals(testName, NameAwareTestClassRunner.getName());
    }

    private void snooze() {
        try {
            // sleep for something between 0 and 1 seconds
            Thread.sleep(Math.abs(new Random().nextLong()) % 1000);
        } catch (InterruptedException e) {
        }
    }

    private String goodOrBad(String myName, String testNameFull) {
        return myName.equals(testNameFull) ? "knows its name" : "is lost";
    }
}